(+ 3 4 5)
(apply + '(3 4 5))

(define list-reduce
  (lambda (proc default lista)

    (letrec ((really-reduce
              (lambda (proc lista)
                (if (= 1 (length lista))
                    (car lista)
                    (proc (car lista)
                          (really-reduce proc
                                         (cdr lista)))))))
      (if (null? lista)
          default
          (really-reduce proc lista)))))

(define length-and-max
  (lambda (lst)
    (values (length lst)
            (list-reduce max 0 lst))))

(length-and-max '(3 4 1 9 5))

(call-with-values
    (lambda () (length-and-max '(3 4 1 9 5)))
  (lambda (l m)
    (list l m)))

;;1.9.1 Composição

(define o
  (lambda (f g)
    (lambda args
      (call-with-values
          (lambda () (apply g args))
        f))))

(define pi 3.1415926536)
(define square
  (lambda (x) (* x x)))

(define squared-sin
  (o square sin))

(square (sin(/ pi 4)))
(squared-sin(/ pi 4))

;;1.9.2 Currying
(define (curry fun . args)
  (lambda x
    (apply fun ( append args x ))))

(define power2 (curry expt 2))
(power2 10)

(define juros-compostos
  (lambda (i t v)
    (* v (expt (+ 1.0 i) t))))

(define jc2
  (lambda (i t)
    (curry juros-compostos i t)))
(define juros (jc2 0.03 12))
(juros 1000)
